package dao

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"time"

	"catering_sys_api/cmd/api/model"
	"catering_sys_api/cmd/api/pack/consts"
	"catering_sys_api/core/db"
	"catering_sys_api/core/jwt"

	"github.com/cloudwego/hertz/pkg/app"
	"gorm.io/gorm"
)

type BusinessUserDao struct {
	ctx context.Context
}

func NewBusinessUserDao(ctx context.Context) *BusinessUserDao {
	return &BusinessUserDao{ctx: ctx}
}

type BusinessUserVo struct {
	UserId         int    `json:"user_id"`
	RealName       string `json:"real_name"`
	Phone          string `json:"phone"`
	BusinessID     int    `json:"business_id"`
	BusinessName   string `json:"business_name"`
	StartTime      int64  `json:"start_name"`
	EndTime        int64  `json:"end_time"`
	ExpirationTime int64  `json:"expiration_time"`
}

func (b *BusinessUserDao) GetBusinessUserVoByToken(token string) (businessUserVo BusinessUserVo, err error) {
	var (
		customClaims *jwt.CustomClaims
		redisToken   string
	)
	customClaims, err = jwt.ParseToken(token, consts.BusinessSecretKey)

	if err != nil {
		return businessUserVo, err
	}
	redisToken, err = b.GetToken(customClaims.UserId)

	if err != nil {
		return businessUserVo, err
	}
	if redisToken != token {
		return businessUserVo, errors.New("用户token不存在")
	}

	businessUserVo, err = b.GetBusinessUserVoByUserIdFromCache(customClaims.UserId)
	//更新token的过期时间
	_ = b.UpdateTokenExpires(customClaims.UserId)
	return
}

func (b *BusinessUserDao) SaveToken(userId int, token string) (err error) {
	var key string
	key = consts.BUSINESS_TOKEN_KEY + fmt.Sprintf("%d", userId)
	return db.Reids.Set(b.ctx, key, token, 3600*2*time.Second).Err()
}

func (b *BusinessUserDao) UpdateTokenExpires(userId int) (err error) {
	var key string
	key = consts.BUSINESS_TOKEN_KEY + fmt.Sprintf("%d", userId)
	return db.Reids.Expire(b.ctx, key, 3600*2*time.Second).Err()
}

func (b *BusinessUserDao) GetToken(userId int) (token string, err error) {
	var key string
	key = consts.BUSINESS_TOKEN_KEY + fmt.Sprintf("%d", userId)
	token, err = db.Reids.Get(b.ctx, key).Result()
	return
}

func (b *BusinessUserDao) DelToken(userId int) error {
	var key string
	key = consts.BUSINESS_TOKEN_KEY + fmt.Sprintf("%d", userId)
	return db.Reids.Del(b.ctx, key).Err()
}

// mysql中获取用户信息
func (b *BusinessUserDao) GetBusinessUserVoByUserId(userId int) (businessUserVo BusinessUserVo, err error) {
	var (
		business     model.Business
		businessUser model.BusinessUser
	)
	err = db.DB.Model(model.BusinessUser{}).Where("id = ?", userId).First(&businessUser).Error

	if err != nil && gorm.ErrRecordNotFound == err {
		return businessUserVo, errors.New("该商户账号不存在")
	}
	if err != nil {
		return businessUserVo, err
	}
	if businessUser.Status != model.BusinessUserStatusEnable {
		return businessUserVo, errors.New("该商户账号已被禁用")
	}

	err = db.DB.Model(model.Business{}).Where("id = ?", businessUser.BusinessID).First(&business).Error
	if err != nil && gorm.ErrRecordNotFound == err {
		return businessUserVo, errors.New("该商户不存在")
	}
	if err != nil {
		return businessUserVo, err
	}

	if business.Status != model.BusinessUserStatusEnable {
		return businessUserVo, errors.New("该商户已被禁用")
	}
	businessUserVo.UserId = businessUser.ID
	businessUserVo.RealName = businessUser.RealName
	businessUserVo.Phone = businessUser.Phone
	businessUserVo.BusinessID = business.ID
	businessUserVo.BusinessName = business.Name
	businessUserVo.StartTime = business.StartTime
	businessUserVo.EndTime = business.EndTime
	businessUserVo.ExpirationTime = time.Now().Unix() + 2*3600 //2个小时候自动更新用户信息
	return businessUserVo, nil
}

// redis中获取用户信息
func (b *BusinessUserDao) GetBusinessUserVoByUserIdFromCache(userId int) (businessUserVo BusinessUserVo, err error) {
	var (
		key          string
		userInfoJson string
		userInfoByte []byte
		currentTime  int64
	)
	key = consts.BUSINESS_USERINFO_KEY + fmt.Sprintf("%d", userId)
	currentTime = time.Now().Unix()
	userInfoJson = db.Reids.Get(b.ctx, key).Val()
	if userInfoJson != "" {
		//REDIS中取出的数据
		err = json.Unmarshal([]byte(userInfoJson), &businessUserVo)
	}

	if err == nil || businessUserVo.ExpirationTime < currentTime {
		//已过期 或者redis取出来的数据是错误的
		businessUserVo, err = b.GetBusinessUserVoByUserId(userId)
	}

	if err != nil {
		return businessUserVo, err
	}
	businessUserVo.ExpirationTime = currentTime
	userInfoByte, _ = json.Marshal(businessUserVo)
	db.Reids.Set(b.ctx, key, string(userInfoByte), 0)

	return
}

// 获取数据
func (b *BusinessUserDao) GetBusinessUserVoFromC(c *app.RequestContext) (businessUserVo BusinessUserVo, err error) {
	businessUserVo.UserId = c.GetInt("user_id")
	businessUserVo.RealName = c.GetString("real_name")
	businessUserVo.Phone = c.GetString("phone")
	businessUserVo.BusinessID = c.GetInt("business_id")
	businessUserVo.BusinessName = c.GetString("business_name")
	businessUserVo.ExpirationTime = c.GetInt64("expiration_time")
	businessUserVo.StartTime = c.GetInt64("start_time")
	businessUserVo.EndTime = c.GetInt64("end_time")
	return
}

// mysql中获取用户信息
func (b *BusinessUserDao) GetBusinessUserByPhone(phone string, businessUser *model.BusinessUser) (err error) {
	var (
		business model.Business
	)
	err = db.DB.Model(model.BusinessUser{}).Where("phone = ?", phone).First(businessUser).Error
	if err != nil {
		return errors.New("该商户账号不存在")
	}
	if businessUser.Status != model.BusinessUserStatusEnable {
		return errors.New("该商户账号已被禁用")
	}

	err = db.DB.Model(model.Business{}).Where("id = ?", businessUser.BusinessID).First(&business).Error
	if err != nil && gorm.ErrRecordNotFound == err {
		return errors.New("该商户不存在")
	}
	if err != nil {
		return err
	}

	if business.Status != model.BusinessUserStatusEnable {
		return errors.New("该商户已被禁用")
	}

	return nil
}
